import { BadRequestException, Injectable } from '@nestjs/common';
import { CreateTaskDto } from './dto/create-task.dto';
import { UpdateTaskDto } from './dto/update-task.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Task } from './entities/task.entity';
import { Between, FindOptionsWhere, Like, Repository } from 'typeorm';
import { taskQueryVo } from '@/common/interface';
import { IPaginationOptions, paginate } from 'nestjs-typeorm-paginate';
@Injectable()
export class TaskService {
  fields: string[];
  constructor(
    @InjectRepository(Task) private readonly taskRepository: Repository<Task>
  ) {
    this.fields = ['name', 'desc', 'level', 'type', 'status', 'adventure'];
  }

  findOneByName(name: string) {
    return this.taskRepository.findOne({
      where: { name }
    });
  }

  async create(createTaskDto: CreateTaskDto) {
    // 重名
    const hasTask = await this.findOneByName(createTaskDto.name);

    if (hasTask) {
      throw new BadRequestException({ code: 400, message: '任务已存在' });
    }

    // 实体实例
    const task = new Task();
    const fields = [...new Set(this.fields)];
    fields.forEach((v) => {
      task[v] = createTaskDto[v];
    });

    this.taskRepository.save(task);
  }

  findAll(options: IPaginationOptions, taskQueryVo: taskQueryVo) {
    const { name, queryDate } = taskQueryVo;
    const where: FindOptionsWhere<Task> = {};
    if (name) {
      where.name = Like(`%${name}%`);
    }
    if (queryDate?.length > 0) {
      where.createdAt = Between(queryDate[0], queryDate[1]);
    }

    return paginate(this.taskRepository, options, { where });
  }

  findOne(id: number) {
    return this.taskRepository.findOne({
      where: { id }
    });
  }

  update(updateTaskDto: UpdateTaskDto) {
    const task = new Task();
    const fields = [...new Set(this.fields), 'id'];
    fields.forEach((v) => {
      task[v] = updateTaskDto[v];
    });

    return this.taskRepository.save(task);
  }

  remove(id: number) {
    return this.taskRepository.delete(id);
  }

  // 分配任务
  async allotTaskToAdventure(id: number, adventureId: number) {
    const task = await this.findOne(id);

    // 任务关联 冒险者工会

    // task.adventure =
  }
}
